package com.jrx.anytxn.transaction.handler;

import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.feign.api.request.LoanPayOffReq;
import com.jrx.anytxn.i18n.response.TxnPage;
import com.jrx.anytxn.i18n.response.TxnRespResult;
import com.jrx.anytxn.transaction.dto.common.CommonReq;
import com.jrx.anytxn.transaction.dto.payment.AdvanceSettleTrialRes;
import com.jrx.anytxn.transaction.dto.payment.BillPayReq;
import com.jrx.anytxn.transaction.dto.payment.BillPayTrailReq;
import com.jrx.anytxn.transaction.dto.payment.BillPayTrailRes;
import com.jrx.anytxn.transaction.dto.payment.BillPrepayNextReq;
import com.jrx.anytxn.transaction.dto.payment.BillPrepayNextRes;
import com.jrx.anytxn.transaction.dto.payment.CustPayOffQueryRes;
import com.jrx.anytxn.transaction.dto.payment.CustRepaymentQueryReq;
import com.jrx.anytxn.transaction.dto.payment.CustRepaymentQueryRes;
import com.jrx.anytxn.transaction.dto.payment.CustomerDebtQueryRes;
import com.jrx.anytxn.transaction.dto.payment.DelinquencyDebtQueryRes;
import com.jrx.anytxn.transaction.dto.payment.DelinquencyPaymentReq;
import com.jrx.anytxn.transaction.dto.payment.DelinquencyTrialReq;
import com.jrx.anytxn.transaction.dto.payment.DelinquencyTrialRes;
import com.jrx.anytxn.transaction.dto.payment.EtlSettleReq;
import com.jrx.anytxn.transaction.dto.payment.EtlSettleRes;
import com.jrx.anytxn.transaction.dto.payment.HandlePaymentReq;
import com.jrx.anytxn.transaction.dto.payment.HandleSkipPayReq;
import com.jrx.anytxn.transaction.dto.payment.HandleSkipPayRes;
import com.jrx.anytxn.transaction.dto.payment.LoanRepaymentQueryReq;
import com.jrx.anytxn.transaction.dto.payment.LoanRepaymentQueryRes;
import com.jrx.anytxn.transaction.dto.payment.LoanStagingRes;
import com.jrx.anytxn.transaction.dto.payment.LoanStagingTrailReq;
import com.jrx.anytxn.transaction.dto.payment.LoanStagingTrailRes;
import com.jrx.anytxn.transaction.dto.payment.OnDuePayReq;
import com.jrx.anytxn.transaction.dto.payment.OnDuePayTrialReq;
import com.jrx.anytxn.transaction.dto.payment.OnDuePayTrialRes;
import com.jrx.anytxn.transaction.dto.payment.PaymentAccessCheckReq;
import com.jrx.anytxn.transaction.dto.payment.PaymentAccessCheckRes;
import com.jrx.anytxn.transaction.dto.payment.PaymentRecordQueryReq;
import com.jrx.anytxn.transaction.dto.payment.PaymentRecordQueryRes;
import com.jrx.anytxn.transaction.dto.payment.PaymentReq;
import com.jrx.anytxn.transaction.dto.payment.PaymentRes;
import com.jrx.anytxn.transaction.dto.payment.PaymentStatusQueryReq;
import com.jrx.anytxn.transaction.dto.payment.PaymentStatusQueryRes;
import com.jrx.anytxn.transaction.dto.payment.PaymentTrialReq;
import com.jrx.anytxn.transaction.dto.payment.PrePayReq;
import com.jrx.anytxn.transaction.dto.payment.PrePayRes;
import com.jrx.anytxn.transaction.dto.payment.PrePayTrialReq;
import com.jrx.anytxn.transaction.dto.payment.PrePayTrialRes;
import com.jrx.anytxn.transaction.dto.payment.RefundReq;
import com.jrx.anytxn.transaction.dto.payment.RefundRes;
import com.jrx.anytxn.transaction.dto.payment.ThirdPartyPaymentQueryReq;
import com.jrx.anytxn.transaction.dto.payment.ThirdPartyPaymentQueryRes;
import com.jrx.anytxn.transaction.dto.payment.ThirdPartyPaymentRep;
import com.jrx.anytxn.transaction.dto.payment.ThirdPartyPaymentRes;
import com.jrx.anytxn.transaction.entity.TlPaymentLog;
import com.jrx.anytxn.transaction.entity.TlWaivePaymentLog;

import java.util.Date;
import java.util.List;

/**
 * 还款handler接口
 *
 * @author zhenghaopu
 * date: 2019/9/24
 */
public interface IPaymentHandler {

    /**
     * 提前结清还款试算
     *
     * @param paymentTrialReq 试算请求req
     * @return void
     * @author zhenghaopu
     * date: 2019/9/24 10:16
     */
    AdvanceSettleTrialRes preterminationTrail(PaymentTrialReq paymentTrialReq) throws TxnException;

    /**
     * 逾期还款试算
     *
     * @param paymentTrialReq 试算请求req
     * @return void
     * @author zhenghaopu
     * date: 2019/9/24 10:16
     */
    DelinquencyTrialRes overdueTrail(DelinquencyTrialReq paymentTrialReq) throws TxnException;

    /**
     * 提前结清还款
     *
     * @param paymentReq 还款请求req
     * @return com.jrx.anytxn.transaction.dto.payment.PaymentRes 还款res
     * @author zhenghaopu
     * date: 2019/9/24 10:18
     */
    PaymentRes preterminationRepayment(PaymentReq paymentReq) throws TxnException;

    /**
     * 逾期还款
     *
     * @param delinquencyPaymentReq 逾期还款请求req
     * @return com.jrx.anytxn.transaction.dto.payment.PaymentRes 还款res
     * @author zhenghaopu
     * date: 2019/9/24 10:18
     */
    PaymentRes overdueRepayment(DelinquencyPaymentReq delinquencyPaymentReq) throws TxnException;

    /**
     * 还款状态查询
     *
     * @param paymentStatusQueryReq 还款状态查询req
     * @return com.jrx.anytxn.transaction.dto.payment.PaymentStatusQueryRes 还款状态查询res
     * @author zhenghaopu
     * date: 2019/9/24 10:19
     */
    PaymentStatusQueryRes getPaymentStatus(PaymentStatusQueryReq paymentStatusQueryReq) throws TxnException;

    /**
     * 正常流程还款分配
     *
     * @param tlPaymentLog 还款流水信息
     * @author zhenghaopu
     * date: 2019/9/24 10:19
     */
    void paymentAllocation(TlPaymentLog tlPaymentLog) throws Exception;

    /**
     * 差错调用还款分配
     *
     * @param tlPaymentLogs
     * @param bussinessDate
     * @throws TxnException
     */
    void dealAllocation(TlPaymentLog tlPaymentLogs, Date bussinessDate) throws Exception;

    /**
     * 提前还款试算
     *
     * @param prePayTrialReq
     * @return
     */
    PrePayTrialRes prePayTrail(PrePayTrialReq prePayTrialReq) throws TxnException;

    /**
     * 提前还款
     *
     * @param prePayReq
     * @return
     */
    PrePayRes prePay(PrePayReq prePayReq) throws TxnException;

    /**
     * 正常还款试算
     *
     * @param onDuePayTrialReq
     * @return
     */
    OnDuePayTrialRes onDuePayTrial(OnDuePayTrialReq onDuePayTrialReq) throws TxnException;

    /**
     * 正常还款
     *
     * @param onDuePayReq
     * @return
     */
    PaymentRes onDuePay(OnDuePayReq onDuePayReq) throws TxnException;

    /**
     * 还款记录查询
     *
     * @param paymentRecordQueryReq 还款记录查询请求
     * @return 还款记录
     * @throws TxnBizException 业务异常
     */
    PaymentRecordQueryRes queryPaymentRecord(PaymentRecordQueryReq paymentRecordQueryReq) throws TxnBizException;

    /**
     * 逾期欠款明细查询
     *
     * @param commonReq 逾期欠款明细查询请求
     * @return 逾期欠款明细
     * @throws TxnBizException 业务异常
     */
    DelinquencyDebtQueryRes queryDelinquencyDebt(CommonReq commonReq) throws TxnException;

    /**
     * 客户欠款查询
     *
     * @param commonReq 通用请求
     * @return 客户欠款
     * @throws TxnBizException 业务异常
     */
    CustomerDebtQueryRes queryCustomerDebt(CommonReq commonReq) throws TxnException;

    /**
     * 账单分期试算
     *
     * @param loanStagingTrailReq
     * @return
     */
    LoanStagingTrailRes loanStagingTrail(LoanStagingTrailReq loanStagingTrailReq) throws Exception;

    /**
     * 账单分期
     *
     * @param loanStagingTrailReq
     * @return
     */
    LoanStagingRes loanStaging(LoanStagingTrailReq loanStagingTrailReq) throws Exception;

    /**
     * 账单分期还款分配
     *
     * @param stagingLoanId 账单分期订单号
     */
    void loanStagingAllocation(String stagingLoanId) throws TxnBizException;

    /**
     * 账单还款
     *
     * @param billPayReq
     * @return
     */
    PaymentRes billPay(BillPayReq billPayReq) throws TxnException;

    /**
     * 还款分配
     *
     * @param log
     */
    void paymentWaiveAllocation(TlWaivePaymentLog log) throws TxnBizException;

    /**
     * 还款分配
     *
     * @param tlWaivePaymentLog
     * @param bussinessDate
     * @throws TxnException
     */
    void dealWaiveAllocation(TlWaivePaymentLog tlWaivePaymentLog, Date bussinessDate) throws TxnException;

    /**
     * 手工还款
     *
     * @param handlePaymentReq
     * @param tenantId
     * @return
     * @throws TxnException
     */
    TxnRespResult<PaymentRes> handlePayment(HandlePaymentReq handlePaymentReq, String tenantId, String userId) throws TxnException;

    /**
     * 手工账单还款-跳过扣款步骤
     * @param handlePaymentReq
     * @param tenantId
     * @return
     * @throws TxnException
     */
    TxnRespResult<HandleSkipPayRes> handleBillSkipPay(HandleSkipPayReq handlePaymentReq, String tenantId) throws TxnException;

    /**
     * 手工提前结清-跳过扣款步骤
     * @param handlePaymentReq
     * @param tenantId
     * @return
     * @throws TxnException
     */
    TxnRespResult<HandleSkipPayRes> handlePreTerminationSkipPay(HandleSkipPayReq handlePaymentReq, String tenantId) throws TxnException;

    /**
     * 第三方还款
     *
     * @param thirdPartyPaymentRep
     * @return
     * @throws TxnException
     */
    ThirdPartyPaymentRes thirdPartyPayment(ThirdPartyPaymentRep thirdPartyPaymentRep) throws TxnException;

    /**
     * 代偿回购还款分配
     *
     * @param tlPaymentLog
     * @return
     * @throws TxnException
     */
    void cmpsCrtAllocation(TlPaymentLog tlPaymentLog) throws TxnBizException;

    /**
     * 三方还款查询
     *
     * @param thirdPartyPaymentQueryReq
     * @return
     */
    ThirdPartyPaymentQueryRes thirdPartyPaymentQuery(ThirdPartyPaymentQueryReq thirdPartyPaymentQueryReq) throws TxnException;

    /**
     * mq发送还款流水
     *
     * @param topic
     * @param data
     */
    void sendMqPaymentLog(String topic, Object data) throws Exception;

    /**
     * 判断是否有还款处理中的数据
     *
     * @param loanId
     * @param customerId
     * @param tenantId
     * @return
     */
    boolean repaymentLogStatusFlag(String loanId, String customerId, String tenantId);

    /**
     * 判断是否有还款处理中的数据
     *
     * @param loanId
     * @param customerId
     * @param tenantId
     * @return
     */
    boolean repaymentLogStatusFlagWithProducts(String loanId, String customerId, String tenantId, List<String> productIds);

    /**
     * 判断是否有贴息还款处理中的数据
     *
     * @param loanId
     * @param customerId
     * @param tenantId
     * @return
     */
    boolean repaymentWaiveLogStatusFlag(String loanId, String customerId, String tenantId);
    /**
     * 判断是否有贴息还款处理中的数据
     *
     * @param loanId
     * @param customerId
     * @param tenantId
     * @param products
     * @return
     */
    boolean repaymentWaiveLogStatusFlagWithProducts(String loanId, String customerId, String tenantId,List<String> products);

    /**
     * 主动还款准入校验
     *
     * @param paymentAccessCheckReq
     * @return
     */
    PaymentAccessCheckRes paymentAccessCheck(PaymentAccessCheckReq paymentAccessCheckReq) throws TxnBizException;

    /**
     * 退款
     *
     * @param refundReq
     * @return
     */
    RefundRes refund(RefundReq refundReq) throws Exception;

    /**
     * 提前还下期账单
     *
     * @param billPrepayNextReq
     * @return
     */
    BillPrepayNextRes billPrepayNext(BillPrepayNextReq billPrepayNextReq) throws TxnException;

    /**
     * 账单还款试算
     *
     * @param billPayTrailReq
     * @return
     */
    BillPayTrailRes billPayTrail(BillPayTrailReq billPayTrailReq) throws TxnException;

    /**
     * 客户还款记录查询
     *
     * @param custRepaymentQueryReq
     * @return
     */
    CustRepaymentQueryRes custRepaymentQuery(CustRepaymentQueryReq custRepaymentQueryReq) throws TxnException;

    /**
     * 借据结清信息查询-默认只提供给信用就医
     *
     * @param loanPayOffReq
     * @return
     */
    CustPayOffQueryRes loanInfoQuery(LoanPayOffReq loanPayOffReq) throws TxnException;

    /**
     *  结清日期查询
     * @param etlSettleReq
     * @return
     * @throws TxnException
     */
    EtlSettleRes getEtlSettleDate(EtlSettleReq etlSettleReq) throws TxnException;

    /**
     * 客户借据还款记录查询
     * @param repaymentQueryReq
     * @return
     */
    LoanRepaymentQueryRes loanRepaymentQuery(LoanRepaymentQueryReq repaymentQueryReq) throws TxnBizException;

    /**
     * 根据产品获取还款日
     * @param loanDate 贷款日期
     * @param paymentDd 默认的还款日
     * @param productId 产品编号
     * @return 还款日
     */
    int getPaymentDayByProductId(Date loanDate, int paymentDd,  String productId);

    /**
     * 根据产品获取账单日
     * @param loanDate 贷款日期
     * @param statementDd 默认的账单日
     * @param productId 产品编号
     * @return 账单日
     */
    int getStatementDayByProductId(Date loanDate, int statementDd, String productId);
}
